Looping Within Projects

Hi everyone, my question is i want to loop within projects. Actually it's a very simple thing to do and it is described in DXL manuel, however, whenever I want to loop in a project which contains other projects I cannot succeed it! And unfortunately i dont know how to sort it out :(. I explain you my ultimate goal which can you a piece of idea about what i'm trying to do.

I have a general project and in this project there are sub-projects and in each sub-project there are folders and in folders finally i have my modules. what i want, when the user clicks the general project, i want to check each module in this general project(to do so i gotta get through sub-projects and after folders and i gotta look inside of each folder) and perform some tasks on this module. but i cannot ask the user to open any module. As i've said, nevertheless i'm stacked in looping this project with its sub-projects and folders and modules, because whenever i try to use the functions explained in DXL manuel, i end up with error messages. What's more there are not enough explanation or exaples in DXL manuel which is quiet irritating.

I would appreciate very much if you guys can give me a hand, because i've been stacked in this loop mania for some time.

Thanks in advance to everyone, who pays attention to this post and for sparing time to give a response to it!
SystemAdmin - Thu Apr 02 06:22:22 EDT 2009

Re: Looping Within Projects
Peter_Albert - Thu Apr 02 10:09:05 EDT 2009

Hi,

The simple solution for a recursive loop through a project is the 'for itemRef in current Project' loop, together with the 'string type(Item i)' perm to identify formal modules:

From the DXL Help:

Item i
for i in current Project do {print fullName(i) ': ' (type i) '\n'}

 


Unfortunately, AFAIK, no recursive loop exists out-of-the-box for folders.

The attached script therefore gives you everything you need for a recursive search through a folder / project / the database.

The interesting part is 'void scanItem(Item i)'. Have a look at 'void scanCurrentFolder()' or 'void scanDatabase()' to see how it is used.

Regards,

Peter

 


Attachments

attachment_14236766_exportModuleTree.dxl

Re: Looping Within Projects
llandale - Thu Apr 02 14:07:47 EDT 2009

I didn't read Albert's code, but the following may get you going as well.

The function below reports modules in a folder, then optionally sub-folders and sub-projects. Display is alphebetical. If you really wanted to report things in the exact order they appear in the GUI, you would recurse sub-folders and projects first, THEN report the modules.

>Louie
 

// LoopThroughProject_Test.dxl
/*
Show looping through the Project
*/
 
bool    g_DoProject     = confirm("[Confirm] to loop through the current Project\n[Cancel] to loop through current Folder")
bool    g_SubProjects   = confirm("[Confirm] to consider sub-projects (if any)\n[Cancel] to ignore sub-projects")
bool    g_SubFolders    = confirm("[Confirm] to consider sub-folders\n[Cancel] to ignore sub-folders")
 
 
Folder  g_fCurr = current
if (null g_fCurr){errorBox("Run from open Folder"); halt} // *** HALT ***
Project g_pCurr = current
if (null g_pCurr and g_DoProject){errorBox("Run from open Project"); halt}        // *** HALT ***
 
Folder  g_fSource
if (g_DoProject)        //-
then  g_fSource = folder(fullName(g_pCurr))     // Source is Project
else  g_fSource = g_fCurr                               // Source is Folder
 
 
//*******************************
void    RecurseFolder(Folder fld, bool DoSubFolds, DoSubProjs)
{     // Recurse modules in the folder, optionally sub-folders and sub-project
        // Function is RECURSIVE enabled.
 
        if (null fld) 
        {  print "\tRecurse, null folder\n"
           return
        }
 
        Item    itm
        string  NameFold        = fullName(fld)
        string  NameItem, TypeItem
        Folder  fldNew
                                // Use Skip list, so items are reported alphebetically,
                                //      in the order they appear in the GUI:
        Skip    skpItems        = createString()        // KEY: 'string' fullName; DATA: 'Item'
 
        print ">" (type(fld)) "\t" fullName(fld) "\n"
 
                        // [0] Stage items in folder in the Skip:
        for itm in fld do
        {  put(skpItems, fullName(itm), itm)
        }
                        // [1] Deal with modules directly in this folder:
        for itm in skpItems do
        {  NameItem = (string key skpItems)
           TypeItem = type(itm)
           if (TypeItem == "Formal"   or
               TypeItem == "Link"     or
               TypeItem == "Descriptive")
           {  print TypeItem "\t" NameFold " \t'" name(itm) "'\n"
                // Deal with the module here.
           }
        }    // end for items, looking for Modules
 
                        // [2] Deal with sub-Projects and sub-Folders, if opted to do so:
        for itm in skpItems do
        {  NameItem = (string key skpItems)
           TypeItem = type(itm)
           if ((TypeItem == "Project" and DoSubProjs) or
               (TypeItem == "Folder"  and DoSubFolds) )
           {  fldNew = folder(itm)
              RecurseFolder(fldNew, DoSubFolds, DoSubProjs)     // *** RECURSION ***
           }
           // else print "\t... ignoring " NameItem "\n"
        }    // end for items, looking for Folders and Projects
 
        delete(skpItems)
}    // end RecurseFolder()
 
print "Start, " name(g_fSource) "\t" g_SubFolders "\t" g_SubProjects "\n"
RecurseFolder(g_fSource, g_SubFolders, g_SubProjects)
 
//      ---- end file LoopThroughProject_Test.dxl ----

Attachments

attachment_14236907_LoopThroughProject_Test.dxl

Re: Looping Within Projects
SystemAdmin - Mon Apr 06 05:59:49 EDT 2009

Peter_Albert - Thu Apr 02 10:09:05 EDT 2009

Hi,

The simple solution for a recursive loop through a project is the 'for itemRef in current Project' loop, together with the 'string type(Item i)' perm to identify formal modules:

From the DXL Help:

Item i
for i in current Project do {print fullName(i) ': ' (type i) '\n'}

 


Unfortunately, AFAIK, no recursive loop exists out-of-the-box for folders.

The attached script therefore gives you everything you need for a recursive search through a folder / project / the database.

The interesting part is 'void scanItem(Item i)'. Have a look at 'void scanCurrentFolder()' or 'void scanDatabase()' to see how it is used.

Regards,

Peter

 

Hi Albert,

i do thank you sincerely for your kind response. I asked ibm to inform me if i get a response but i dont why, i have not been informed so i tought no one sent me an answer and to day by cruiosity i am connected and i saw your answer, i'm going to test it suddenly and i will let you know about the results. thanks again really, your help is greatly appreciated.

Kind regards,

Melih

Re: Looping Within Projects
SystemAdmin - Mon Apr 06 06:02:21 EDT 2009

llandale - Thu Apr 02 14:07:47 EDT 2009

I didn't read Albert's code, but the following may get you going as well.

The function below reports modules in a folder, then optionally sub-folders and sub-projects. Display is alphebetical. If you really wanted to report things in the exact order they appear in the GUI, you would recurse sub-folders and projects first, THEN report the modules.

>Louie
 

// LoopThroughProject_Test.dxl
/*
Show looping through the Project
*/
 
bool    g_DoProject     = confirm("[Confirm] to loop through the current Project\n[Cancel] to loop through current Folder")
bool    g_SubProjects   = confirm("[Confirm] to consider sub-projects (if any)\n[Cancel] to ignore sub-projects")
bool    g_SubFolders    = confirm("[Confirm] to consider sub-folders\n[Cancel] to ignore sub-folders")
 
 
Folder  g_fCurr = current
if (null g_fCurr){errorBox("Run from open Folder"); halt} // *** HALT ***
Project g_pCurr = current
if (null g_pCurr and g_DoProject){errorBox("Run from open Project"); halt}        // *** HALT ***
 
Folder  g_fSource
if (g_DoProject)        //-
then  g_fSource = folder(fullName(g_pCurr))     // Source is Project
else  g_fSource = g_fCurr                               // Source is Folder
 
 
//*******************************
void    RecurseFolder(Folder fld, bool DoSubFolds, DoSubProjs)
{     // Recurse modules in the folder, optionally sub-folders and sub-project
        // Function is RECURSIVE enabled.
 
        if (null fld) 
        {  print "\tRecurse, null folder\n"
           return
        }
 
        Item    itm
        string  NameFold        = fullName(fld)
        string  NameItem, TypeItem
        Folder  fldNew
                                // Use Skip list, so items are reported alphebetically,
                                //      in the order they appear in the GUI:
        Skip    skpItems        = createString()        // KEY: 'string' fullName; DATA: 'Item'
 
        print ">" (type(fld)) "\t" fullName(fld) "\n"
 
                        // [0] Stage items in folder in the Skip:
        for itm in fld do
        {  put(skpItems, fullName(itm), itm)
        }
                        // [1] Deal with modules directly in this folder:
        for itm in skpItems do
        {  NameItem = (string key skpItems)
           TypeItem = type(itm)
           if (TypeItem == "Formal"   or
               TypeItem == "Link"     or
               TypeItem == "Descriptive")
           {  print TypeItem "\t" NameFold " \t'" name(itm) "'\n"
                // Deal with the module here.
           }
        }    // end for items, looking for Modules
 
                        // [2] Deal with sub-Projects and sub-Folders, if opted to do so:
        for itm in skpItems do
        {  NameItem = (string key skpItems)
           TypeItem = type(itm)
           if ((TypeItem == "Project" and DoSubProjs) or
               (TypeItem == "Folder"  and DoSubFolds) )
           {  fldNew = folder(itm)
              RecurseFolder(fldNew, DoSubFolds, DoSubProjs)     // *** RECURSION ***
           }
           // else print "\t... ignoring " NameItem "\n"
        }    // end for items, looking for Folders and Projects
 
        delete(skpItems)
}    // end RecurseFolder()
 
print "Start, " name(g_fSource) "\t" g_SubFolders "\t" g_SubProjects "\n"
RecurseFolder(g_fSource, g_SubFolders, g_SubProjects)
 
//      ---- end file LoopThroughProject_Test.dxl ----

Hi llandale,

Perhaps it will be the same answer that i sent tp Albert but unfortunately i saw your answers at the same so the content of the message rests unchanged.

But i would like to thank you also for paying attention to my problem and it's really and really very kind. I asked ibm to inform me if i get a response but i dont why, i have not been informed so i tought no one sent me an answer and to day by cruiosity i am connected and i saw your answer, i'm going to test it suddenly and i will let you know about the results. thanks again really, your help is greatly appreciated.

Kind regards,

Melih

Re: Looping Within Projects
SystemAdmin - Mon Apr 06 06:07:04 EDT 2009

Peter_Albert - Thu Apr 02 10:09:05 EDT 2009

Hi,

The simple solution for a recursive loop through a project is the 'for itemRef in current Project' loop, together with the 'string type(Item i)' perm to identify formal modules:

From the DXL Help:

Item i
for i in current Project do {print fullName(i) ': ' (type i) '\n'}

 


Unfortunately, AFAIK, no recursive loop exists out-of-the-box for folders.

The attached script therefore gives you everything you need for a recursive search through a folder / project / the database.

The interesting part is 'void scanItem(Item i)'. Have a look at 'void scanCurrentFolder()' or 'void scanDatabase()' to see how it is used.

Regards,

Peter

 

Hi Peter, (i do not know you prefer which name of yours perhaps both of them so sorry to call you Peter if it bothers you)

I ran your code but i encountered two problems at the beginning, this might be perhaps because my version is not recent enough, this is why some functions are not supported, i do not know. Here are the problems i viewed:

#include <../include/read_module.inc>
#include <../include/create_date.inc>

-E- DXL: <Line:8> could not open include file (../include/read_module.inc) (No such file or directory)
-E- DXL: <Line:9> could not open include file (../include/create_date.inc) (No such file or directory)

Re: Looping Within Projects
SystemAdmin - Mon Apr 06 06:19:23 EDT 2009

llandale - Thu Apr 02 14:07:47 EDT 2009

I didn't read Albert's code, but the following may get you going as well.

The function below reports modules in a folder, then optionally sub-folders and sub-projects. Display is alphebetical. If you really wanted to report things in the exact order they appear in the GUI, you would recurse sub-folders and projects first, THEN report the modules.

>Louie
 

// LoopThroughProject_Test.dxl
/*
Show looping through the Project
*/
 
bool    g_DoProject     = confirm("[Confirm] to loop through the current Project\n[Cancel] to loop through current Folder")
bool    g_SubProjects   = confirm("[Confirm] to consider sub-projects (if any)\n[Cancel] to ignore sub-projects")
bool    g_SubFolders    = confirm("[Confirm] to consider sub-folders\n[Cancel] to ignore sub-folders")
 
 
Folder  g_fCurr = current
if (null g_fCurr){errorBox("Run from open Folder"); halt} // *** HALT ***
Project g_pCurr = current
if (null g_pCurr and g_DoProject){errorBox("Run from open Project"); halt}        // *** HALT ***
 
Folder  g_fSource
if (g_DoProject)        //-
then  g_fSource = folder(fullName(g_pCurr))     // Source is Project
else  g_fSource = g_fCurr                               // Source is Folder
 
 
//*******************************
void    RecurseFolder(Folder fld, bool DoSubFolds, DoSubProjs)
{     // Recurse modules in the folder, optionally sub-folders and sub-project
        // Function is RECURSIVE enabled.
 
        if (null fld) 
        {  print "\tRecurse, null folder\n"
           return
        }
 
        Item    itm
        string  NameFold        = fullName(fld)
        string  NameItem, TypeItem
        Folder  fldNew
                                // Use Skip list, so items are reported alphebetically,
                                //      in the order they appear in the GUI:
        Skip    skpItems        = createString()        // KEY: 'string' fullName; DATA: 'Item'
 
        print ">" (type(fld)) "\t" fullName(fld) "\n"
 
                        // [0] Stage items in folder in the Skip:
        for itm in fld do
        {  put(skpItems, fullName(itm), itm)
        }
                        // [1] Deal with modules directly in this folder:
        for itm in skpItems do
        {  NameItem = (string key skpItems)
           TypeItem = type(itm)
           if (TypeItem == "Formal"   or
               TypeItem == "Link"     or
               TypeItem == "Descriptive")
           {  print TypeItem "\t" NameFold " \t'" name(itm) "'\n"
                // Deal with the module here.
           }
        }    // end for items, looking for Modules
 
                        // [2] Deal with sub-Projects and sub-Folders, if opted to do so:
        for itm in skpItems do
        {  NameItem = (string key skpItems)
           TypeItem = type(itm)
           if ((TypeItem == "Project" and DoSubProjs) or
               (TypeItem == "Folder"  and DoSubFolds) )
           {  fldNew = folder(itm)
              RecurseFolder(fldNew, DoSubFolds, DoSubProjs)     // *** RECURSION ***
           }
           // else print "\t... ignoring " NameItem "\n"
        }    // end for items, looking for Folders and Projects
 
        delete(skpItems)
}    // end RecurseFolder()
 
print "Start, " name(g_fSource) "\t" g_SubFolders "\t" g_SubProjects "\n"
RecurseFolder(g_fSource, g_SubFolders, g_SubProjects)
 
//      ---- end file LoopThroughProject_Test.dxl ----

Hi Louie,

your code runs perfectly well, and it's really quiet functional. Thanks again. Do you think that using this code i can add functions like if the module is !null do this then close the module? Or would be difficiult to integrate these parts so i'd better write another code using your approach?

thanks again

Re: Looping Within Projects
SystemAdmin - Mon Apr 06 06:52:32 EDT 2009

llandale - Thu Apr 02 14:07:47 EDT 2009

I didn't read Albert's code, but the following may get you going as well.

The function below reports modules in a folder, then optionally sub-folders and sub-projects. Display is alphebetical. If you really wanted to report things in the exact order they appear in the GUI, you would recurse sub-folders and projects first, THEN report the modules.

>Louie
 

// LoopThroughProject_Test.dxl
/*
Show looping through the Project
*/
 
bool    g_DoProject     = confirm("[Confirm] to loop through the current Project\n[Cancel] to loop through current Folder")
bool    g_SubProjects   = confirm("[Confirm] to consider sub-projects (if any)\n[Cancel] to ignore sub-projects")
bool    g_SubFolders    = confirm("[Confirm] to consider sub-folders\n[Cancel] to ignore sub-folders")
 
 
Folder  g_fCurr = current
if (null g_fCurr){errorBox("Run from open Folder"); halt} // *** HALT ***
Project g_pCurr = current
if (null g_pCurr and g_DoProject){errorBox("Run from open Project"); halt}        // *** HALT ***
 
Folder  g_fSource
if (g_DoProject)        //-
then  g_fSource = folder(fullName(g_pCurr))     // Source is Project
else  g_fSource = g_fCurr                               // Source is Folder
 
 
//*******************************
void    RecurseFolder(Folder fld, bool DoSubFolds, DoSubProjs)
{     // Recurse modules in the folder, optionally sub-folders and sub-project
        // Function is RECURSIVE enabled.
 
        if (null fld) 
        {  print "\tRecurse, null folder\n"
           return
        }
 
        Item    itm
        string  NameFold        = fullName(fld)
        string  NameItem, TypeItem
        Folder  fldNew
                                // Use Skip list, so items are reported alphebetically,
                                //      in the order they appear in the GUI:
        Skip    skpItems        = createString()        // KEY: 'string' fullName; DATA: 'Item'
 
        print ">" (type(fld)) "\t" fullName(fld) "\n"
 
                        // [0] Stage items in folder in the Skip:
        for itm in fld do
        {  put(skpItems, fullName(itm), itm)
        }
                        // [1] Deal with modules directly in this folder:
        for itm in skpItems do
        {  NameItem = (string key skpItems)
           TypeItem = type(itm)
           if (TypeItem == "Formal"   or
               TypeItem == "Link"     or
               TypeItem == "Descriptive")
           {  print TypeItem "\t" NameFold " \t'" name(itm) "'\n"
                // Deal with the module here.
           }
        }    // end for items, looking for Modules
 
                        // [2] Deal with sub-Projects and sub-Folders, if opted to do so:
        for itm in skpItems do
        {  NameItem = (string key skpItems)
           TypeItem = type(itm)
           if ((TypeItem == "Project" and DoSubProjs) or
               (TypeItem == "Folder"  and DoSubFolds) )
           {  fldNew = folder(itm)
              RecurseFolder(fldNew, DoSubFolds, DoSubProjs)     // *** RECURSION ***
           }
           // else print "\t... ignoring " NameItem "\n"
        }    // end for items, looking for Folders and Projects
 
        delete(skpItems)
}    // end RecurseFolder()
 
print "Start, " name(g_fSource) "\t" g_SubFolders "\t" g_SubProjects "\n"
RecurseFolder(g_fSource, g_SubFolders, g_SubProjects)
 
//      ---- end file LoopThroughProject_Test.dxl ----

Hi Louie again,

I tried to modify a little bit your code to see if i can use it for my own purposes and i figured out that yes i can! :D But what i dont understand even if the code does exactly what i asked him to do, and the results are correct also i receive a run-time error but despite this error i can get all the information i need correctly. Only I want to know why this happens, because when i try to display these resultats i think it's going to pose some problems.

Here is the code (a little bit modified :$)
 

// LoopThroughProject_Test.dxl
/*
Show looping through the Project
*/
 
bool    g_DoProject     = confirm("[Confirm] to loop through the current Project\n[Cancel] to loop through current Folder")
bool    g_SubProjects   = confirm("[Confirm] to consider sub-projects (if any)\n[Cancel] to ignore sub-projects")
bool    g_SubFolders    = confirm("[Confirm] to consider sub-folders\n[Cancel] to ignore sub-folders")
 
 
Folder  g_fCurr = current
if (null g_fCurr){errorBox("Run from open Folder"); halt} // *** HALT ***
Project g_pCurr = current
if (null g_pCurr and g_DoProject){errorBox("Run from open Project"); halt}        // *** HALT ***
 
Folder  g_fSource
if (g_DoProject)        //-
then  g_fSource = folder(fullName(g_pCurr))     // Source is Project
else  g_fSource = g_fCurr                               // Source is Folder
 
 
//*******************************
void    RecurseFolder(Folder fld, bool DoSubFolds, DoSubProjs)
{     // Recurse modules in the folder, optionally sub-folders and sub-project
        // Function is RECURSIVE enabled.
 
        if (null fld) 
        {  print "\tRecurse, null folder\n"
           return
        }
 
        Item    itm
        string  NameFold        = fullName(fld)
        string  NameItem, TypeItem
        Folder  fldNew
                                // Use Skip list, so items are reported alphebetically,
                                //      in the order they appear in the GUI:
        Skip    skpItems        = createString()        // KEY: 'string' fullName; DATA: 'Item'
 
        // print ">" (type(fld)) "\t" fullName(fld) "\n"
 
                        // [0] Stage items in folder in the Skip:
        for itm in fld do
        {  put(skpItems, fullName(itm), itm)
        }
                        // [1] Deal with modules directly in this folder:
        for itm in skpItems do
        {  NameItem = (string key skpItems)
           TypeItem = type(itm)
           if (TypeItem == "Formal"   or
               TypeItem == "Link"     or
               TypeItem == "Descriptive")
           {  //print TypeItem "\t" NameFold " \t'" name(itm) "'\n"
                // Deal with the module here.
                     read(NameItem, false)
                     int nombreDeTitre = 0
                    Object o
                    for o in current Module do{
                    string TdeO = o."Object Text"
                    if(!null TdeO) nombreDeTitre++
                   }
                   print TypeItem "\t" NameFold " \t'" name(itm)  "the number of requirements:"
                   print nombreDeTitre
                   
           }
        }    // end for items, looking for Modules
 
                        // [2] Deal with sub-Projects and sub-Folders, if opted to do so:
        for itm in skpItems do
        {  NameItem = (string key skpItems)
           TypeItem = type(itm)
           if ((TypeItem == "Project" and DoSubProjs) or
               (TypeItem == "Folder"  and DoSubFolds) )
           {  fldNew = folder(itm)
              RecurseFolder(fldNew, DoSubFolds, DoSubProjs)     // *** RECURSION ***
           }
           // else print "\t... ignoring " NameItem "\n"
        }    // end for items, looking for Folders and Projects
 
        delete(skpItems)
}    // end RecurseFolder()
 
print "Start, " name(g_fSource) "\t" g_SubFolders "\t" g_SubProjects "\n"
RecurseFolder(g_fSource, g_SubFolders, g_SubProjects)
 
//      ---- end file LoopThroughProject_Test.dxl ----

 


Thanks again Louie

 

Re: Looping Within Projects
Peter_Albert - Mon Apr 06 08:34:35 EDT 2009

SystemAdmin - Mon Apr 06 06:07:04 EDT 2009
Hi Peter, (i do not know you prefer which name of yours perhaps both of them so sorry to call you Peter if it bothers you)

I ran your code but i encountered two problems at the beginning, this might be perhaps because my version is not recent enough, this is why some functions are not supported, i do not know. Here are the problems i viewed:

#include <../include/read_module.inc>
#include <../include/create_date.inc>

-E- DXL: <Line:8> could not open include file (../include/read_module.inc) (No such file or directory)
-E- DXL: <Line:9> could not open include file (../include/create_date.inc) (No such file or directory)

Hi Melih,

sorry for the problem; I made a mistake by posting the script with dependencies on other local include files. I updated the attached script to run without the include files. But you would still need to modify the line

const string OUT_FILE = "H://Desktop//DOORS_moduleTree.csv"

to point to an existing directory on your computer.
As for your problem with Louie's script, your problem is that you are trying to retrieve the "Object Text" attribute from objects in all types of modules. However, "Object Text" only exists in formal modules, but not in link modules. If you change the lines

if (TypeItem == "Formal"    or
               TypeItem == "Link"     or
               TypeItem == "Descriptive")

to

if (TypeItem == "Formal")

the script should do what you expected.
Regards,

Peter


Attachments

attachment_14237743_exportModuleTree.dxl

Re: Looping Within Projects
SystemAdmin - Mon Apr 06 08:47:21 EDT 2009

Peter_Albert - Mon Apr 06 08:34:35 EDT 2009

Hi Melih,

sorry for the problem; I made a mistake by posting the script with dependencies on other local include files. I updated the attached script to run without the include files. But you would still need to modify the line

const string OUT_FILE = "H://Desktop//DOORS_moduleTree.csv"

to point to an existing directory on your computer.
As for your problem with Louie's script, your problem is that you are trying to retrieve the "Object Text" attribute from objects in all types of modules. However, "Object Text" only exists in formal modules, but not in link modules. If you change the lines

if (TypeItem == "Formal"    or
               TypeItem == "Link"     or
               TypeItem == "Descriptive")

to

if (TypeItem == "Formal")

the script should do what you expected.
Regards,

Peter

Hi Peter,

thanks for the updated file, i am gonna have a look at it in a few minutes, and for Louie's part, yes you are right, i was trying to do some changes but as you ve said it is because of links. thanks you guys, with the help of yours, i learn many things. Unfortunately manuel is not that well explained so i know that i'm becoming time consuming but i can't see another way-out :(

Re: Looping Within Projects
SystemAdmin - Mon Apr 06 09:48:19 EDT 2009

Peter_Albert - Mon Apr 06 08:34:35 EDT 2009

Hi Melih,

sorry for the problem; I made a mistake by posting the script with dependencies on other local include files. I updated the attached script to run without the include files. But you would still need to modify the line

const string OUT_FILE = "H://Desktop//DOORS_moduleTree.csv"

to point to an existing directory on your computer.
As for your problem with Louie's script, your problem is that you are trying to retrieve the "Object Text" attribute from objects in all types of modules. However, "Object Text" only exists in formal modules, but not in link modules. If you change the lines

if (TypeItem == "Formal"    or
               TypeItem == "Link"     or
               TypeItem == "Descriptive")

to

if (TypeItem == "Formal")

the script should do what you expected.
Regards,

Peter

Peter may i ask you another question please?

I'm trying to put a multiList in this structure but unfortunately when i create it in the void, it does not work i mean it does not appear, it does not give an error message either. When i create the list out of the void function, i can't get variable values in the function. What i was intended to do to rephrase this function in order to get what i need, but i believe it's not the most logical way to do it. Can you give me an idea?

Re: Looping Within Projects
Peter_Albert - Mon Apr 06 10:52:24 EDT 2009

SystemAdmin - Mon Apr 06 09:48:19 EDT 2009
Peter may i ask you another question please?

I'm trying to put a multiList in this structure but unfortunately when i create it in the void, it does not work i mean it does not appear, it does not give an error message either. When i create the list out of the void function, i can't get variable values in the function. What i was intended to do to rephrase this function in order to get what i need, but i believe it's not the most logical way to do it. Can you give me an idea?

Hmm, I do not fully understand what you are actually doing, but I think you need a bit of clarification w.r.t. the scope of variables, i.e. the level on which variables exist. From the DXL help: "In general, identifiers are in scope following their declaration within the current block, and are available within nested blocks."

Basically, global variables defined at the top of your script, outside of any subroutine, are available everywhere. Local variables, defined within a subroutine, are not available in other subroutines, or at the main level.

So, in order to get information out of a subroutine, the first idea could be to use global variables all over the place. While there are occasions when this is actually the way to go, you should generally try to avoid this and use return variables instead.

The following code snippet might highlight the differences:

string s_global = "I am a global string and live everywhere."
 
string doSomething(string s_input)
{
  string s_local = "I am a local variable and only live inside this subroutine."
  string s_return = "I am the return value."
  print "s_global: " s_global "\n"
  print "s_local: " s_local "\n"
  print "s_input: " s_input "\n"
  s_global = s_global "And now I have been modified."
  return s_return
}
 
string s_result = doSomething("I am the input variable")
print "s_global: " s_global "\n"
print "s_result: " s_result "\n"
// Do not try to
// print "s_local: " s_local "\n"
// as 's_local' does not exist at this level

 


I don't know if this actually answers your question ...
Regards,

Peter

 

Re: Looping Within Projects
llandale - Mon Apr 06 15:56:57 EDT 2009

SystemAdmin - Mon Apr 06 06:52:32 EDT 2009

Hi Louie again,

I tried to modify a little bit your code to see if i can use it for my own purposes and i figured out that yes i can! :D But what i dont understand even if the code does exactly what i asked him to do, and the results are correct also i receive a run-time error but despite this error i can get all the information i need correctly. Only I want to know why this happens, because when i try to display these resultats i think it's going to pose some problems.

Here is the code (a little bit modified :$)
 

// LoopThroughProject_Test.dxl
/*
Show looping through the Project
*/
 
bool    g_DoProject     = confirm("[Confirm] to loop through the current Project\n[Cancel] to loop through current Folder")
bool    g_SubProjects   = confirm("[Confirm] to consider sub-projects (if any)\n[Cancel] to ignore sub-projects")
bool    g_SubFolders    = confirm("[Confirm] to consider sub-folders\n[Cancel] to ignore sub-folders")
 
 
Folder  g_fCurr = current
if (null g_fCurr){errorBox("Run from open Folder"); halt} // *** HALT ***
Project g_pCurr = current
if (null g_pCurr and g_DoProject){errorBox("Run from open Project"); halt}        // *** HALT ***
 
Folder  g_fSource
if (g_DoProject)        //-
then  g_fSource = folder(fullName(g_pCurr))     // Source is Project
else  g_fSource = g_fCurr                               // Source is Folder
 
 
//*******************************
void    RecurseFolder(Folder fld, bool DoSubFolds, DoSubProjs)
{     // Recurse modules in the folder, optionally sub-folders and sub-project
        // Function is RECURSIVE enabled.
 
        if (null fld) 
        {  print "\tRecurse, null folder\n"
           return
        }
 
        Item    itm
        string  NameFold        = fullName(fld)
        string  NameItem, TypeItem
        Folder  fldNew
                                // Use Skip list, so items are reported alphebetically,
                                //      in the order they appear in the GUI:
        Skip    skpItems        = createString()        // KEY: 'string' fullName; DATA: 'Item'
 
        // print ">" (type(fld)) "\t" fullName(fld) "\n"
 
                        // [0] Stage items in folder in the Skip:
        for itm in fld do
        {  put(skpItems, fullName(itm), itm)
        }
                        // [1] Deal with modules directly in this folder:
        for itm in skpItems do
        {  NameItem = (string key skpItems)
           TypeItem = type(itm)
           if (TypeItem == "Formal"   or
               TypeItem == "Link"     or
               TypeItem == "Descriptive")
           {  //print TypeItem "\t" NameFold " \t'" name(itm) "'\n"
                // Deal with the module here.
                     read(NameItem, false)
                     int nombreDeTitre = 0
                    Object o
                    for o in current Module do{
                    string TdeO = o."Object Text"
                    if(!null TdeO) nombreDeTitre++
                   }
                   print TypeItem "\t" NameFold " \t'" name(itm)  "the number of requirements:"
                   print nombreDeTitre
                   
           }
        }    // end for items, looking for Modules
 
                        // [2] Deal with sub-Projects and sub-Folders, if opted to do so:
        for itm in skpItems do
        {  NameItem = (string key skpItems)
           TypeItem = type(itm)
           if ((TypeItem == "Project" and DoSubProjs) or
               (TypeItem == "Folder"  and DoSubFolds) )
           {  fldNew = folder(itm)
              RecurseFolder(fldNew, DoSubFolds, DoSubProjs)     // *** RECURSION ***
           }
           // else print "\t... ignoring " NameItem "\n"
        }    // end for items, looking for Folders and Projects
 
        delete(skpItems)
}    // end RecurseFolder()
 
print "Start, " name(g_fSource) "\t" g_SubFolders "\t" g_SubProjects "\n"
RecurseFolder(g_fSource, g_SubFolders, g_SubProjects)
 
//      ---- end file LoopThroughProject_Test.dxl ----

 


Thanks again Louie

 

Your use of 'current Module' is a potential disaster. Stay away from that. Its possible that in my 100s of scripts I've used 'current Module' oddly, but the vast majority of the time I use it for one purpose only: at the top of a script that is intended to be run on an open module. Specifically, most of my scripts start like this:

Module g_mCurr = current
if (null g_mCurr){errorBox("Run from open module"); halt} // **** HALT ****


Thereafter, I refer to 'this' module using variable g_mCurr.

This g_mCurr handle is useful for object loops, but its also useful before commands that presume the 'current module', such as the attribute 'exists' command. For those, you want to set the current module before using the commands, current = g_mCurr in this case.

OK, I lied. The other case I use it is to remember what the current module is, so after I open some modules etc I can reset it back. I do this a fair amount of time in many of my library functions in the massive library.

I know that in old versions of DOORS, the 'current Module' did NOT change when you attempted to open a module that was already open. Maybe they changed that. Anyway, assuming a just-opened module is 'current' is bad programming.

In your case, you should remember the Module handle of the open module and refer to that, getting rid of your reference to 'current Module'. Also, to be clever maybe you want to close a module only after you have actually opened it, letting is stay open if it was already open. Thus, it may look like this:

 

//****************************
Module    fIsOpen(string NameModFull, bool MustBeVisible)
{     // Return the module handle of the open module.
        // [] Module name should be a fully qualified name.
        // [] If MustBeVisible then the module must be open Visible
        //    (that is, if its open invisible return "null".
        // Return null if its not open as specified.
 
        Item    itm
        Module  mod
                // "item" returns whether it exists.
                // "module" below returns only if its open.
        itm      = item(NameModFull)
        if (!null itm)
             mod = module(itm)  // Module handle if its open
        else mod = null
 
        if (!null mod and MustBeVisible and !isVisible(mod))
             mod = null         // Is Open, needs to be Visible, but isn't.
 
//      if (null mod)   print "fIsOpen: NOT open: " NameModFull "\n"
//      else            print "fIsOpen: OPEN    : " NameModFull "\n"
 
        return(mod)
}     // end fIsOpen()
 
//--------------------------
bool    fIsOpen(string NameModFull, bool MustBeVisible)
{     // overloaded, returns true or false
        return (!null fIsOpen(NameModFull, MustBeVisible))
}     // end overloaded fIsOpen()
 
bla bla bla
          // 'false' in these two lines means the module isn't visible:
bool IsOpen = fIsOpen(NameModuleFull, false)
Module mod = read(NameModuleFull, false) // Open it, or get existing handle if already open
if (null mod)
{  warningBox("Cannot open: '" NameModuleFull "'")
}
else
{  Deal with the open module
   if (!IsOpen) close(mod, false)
}



Also, while I'm nit-picking, the 'for obj in Module' loop only finds currently displayed Objects. I'm not sure what that exactly means for invisible modules, but a couple versions ago it meant only objects displayed in the module's default view. Your DXL can rarely depend on that to be all the module your DXL cares about, thus your DXL should be bullet proof, looking at EVERY SINGLE OBJECT, using 'entire', then explicitely ignoring the ones you don't care about:



 

 

for obj in entire mod do
{  if (isDeleted(obj)) continue    // don't care about deleted objects
   if (table(obj) or row(obj) or cell(obj)) continue    // ignore objects in tables
   other checks for this obj
}



The alternative may be to load the module's 'Standard View', then use your 'for obj in mod' loop.

>Louie



 

Re: Looping Within Projects
SystemAdmin - Tue Apr 07 06:01:51 EDT 2009

llandale - Mon Apr 06 15:56:57 EDT 2009

Your use of 'current Module' is a potential disaster. Stay away from that. Its possible that in my 100s of scripts I've used 'current Module' oddly, but the vast majority of the time I use it for one purpose only: at the top of a script that is intended to be run on an open module. Specifically, most of my scripts start like this:

Module g_mCurr = current
if (null g_mCurr){errorBox("Run from open module"); halt} // **** HALT ****


Thereafter, I refer to 'this' module using variable g_mCurr.

This g_mCurr handle is useful for object loops, but its also useful before commands that presume the 'current module', such as the attribute 'exists' command. For those, you want to set the current module before using the commands, current = g_mCurr in this case.

OK, I lied. The other case I use it is to remember what the current module is, so after I open some modules etc I can reset it back. I do this a fair amount of time in many of my library functions in the massive library.

I know that in old versions of DOORS, the 'current Module' did NOT change when you attempted to open a module that was already open. Maybe they changed that. Anyway, assuming a just-opened module is 'current' is bad programming.

In your case, you should remember the Module handle of the open module and refer to that, getting rid of your reference to 'current Module'. Also, to be clever maybe you want to close a module only after you have actually opened it, letting is stay open if it was already open. Thus, it may look like this:

 

//****************************
Module    fIsOpen(string NameModFull, bool MustBeVisible)
{     // Return the module handle of the open module.
        // [] Module name should be a fully qualified name.
        // [] If MustBeVisible then the module must be open Visible
        //    (that is, if its open invisible return "null".
        // Return null if its not open as specified.
 
        Item    itm
        Module  mod
                // "item" returns whether it exists.
                // "module" below returns only if its open.
        itm      = item(NameModFull)
        if (!null itm)
             mod = module(itm)  // Module handle if its open
        else mod = null
 
        if (!null mod and MustBeVisible and !isVisible(mod))
             mod = null         // Is Open, needs to be Visible, but isn't.
 
//      if (null mod)   print "fIsOpen: NOT open: " NameModFull "\n"
//      else            print "fIsOpen: OPEN    : " NameModFull "\n"
 
        return(mod)
}     // end fIsOpen()
 
//--------------------------
bool    fIsOpen(string NameModFull, bool MustBeVisible)
{     // overloaded, returns true or false
        return (!null fIsOpen(NameModFull, MustBeVisible))
}     // end overloaded fIsOpen()
 
bla bla bla
          // 'false' in these two lines means the module isn't visible:
bool IsOpen = fIsOpen(NameModuleFull, false)
Module mod = read(NameModuleFull, false) // Open it, or get existing handle if already open
if (null mod)
{  warningBox("Cannot open: '" NameModuleFull "'")
}
else
{  Deal with the open module
   if (!IsOpen) close(mod, false)
}



Also, while I'm nit-picking, the 'for obj in Module' loop only finds currently displayed Objects. I'm not sure what that exactly means for invisible modules, but a couple versions ago it meant only objects displayed in the module's default view. Your DXL can rarely depend on that to be all the module your DXL cares about, thus your DXL should be bullet proof, looking at EVERY SINGLE OBJECT, using 'entire', then explicitely ignoring the ones you don't care about:



 

 

for obj in entire mod do
{  if (isDeleted(obj)) continue    // don't care about deleted objects
   if (table(obj) or row(obj) or cell(obj)) continue    // ignore objects in tables
   other checks for this obj
}



The alternative may be to load the module's 'Standard View', then use your 'for obj in mod' loop.

>Louie



 

Hi Louie, yes actually assuming that the module we've opened is the current one is not a very brilliant idea. Me too, i do not put it like that however as it was going to be a part of other codes, i was not quiet sure, i used which variable names as module and instead of searching for it for the time being, i used a current Module to change another time. Anyways i really appreciate every critic as you guys are far more experienced than i am i guess, i can learn something with your every single sentence.

And i remarked that i forgot to close the modules that i've opened which was a shame :$, fortunately i ve noticed that, thanks alot.

I think reading and opening modules as you suggested is much more logical so i modified the program as you adviced.

I do really thank you Louie, you're amazing.

Kind regards,

Melih

Re: Looping Within Projects
SystemAdmin - Tue Apr 07 06:05:52 EDT 2009

Peter_Albert - Mon Apr 06 10:52:24 EDT 2009

Hmm, I do not fully understand what you are actually doing, but I think you need a bit of clarification w.r.t. the scope of variables, i.e. the level on which variables exist. From the DXL help: "In general, identifiers are in scope following their declaration within the current block, and are available within nested blocks."

Basically, global variables defined at the top of your script, outside of any subroutine, are available everywhere. Local variables, defined within a subroutine, are not available in other subroutines, or at the main level.

So, in order to get information out of a subroutine, the first idea could be to use global variables all over the place. While there are occasions when this is actually the way to go, you should generally try to avoid this and use return variables instead.

The following code snippet might highlight the differences:

string s_global = "I am a global string and live everywhere."
 
string doSomething(string s_input)
{
  string s_local = "I am a local variable and only live inside this subroutine."
  string s_return = "I am the return value."
  print "s_global: " s_global "\n"
  print "s_local: " s_local "\n"
  print "s_input: " s_input "\n"
  s_global = s_global "And now I have been modified."
  return s_return
}
 
string s_result = doSomething("I am the input variable")
print "s_global: " s_global "\n"
print "s_result: " s_result "\n"
// Do not try to
// print "s_local: " s_local "\n"
// as 's_local' does not exist at this level

 


I don't know if this actually answers your question ...
Regards,

Peter

 

Hi Peter again, i guess because of the time difference between the US causes me to reply a little bit late. Today i read your answer with attention. In fact you explinication answer my problem completely. However i have some difficulties still to implement these returns values, because when i try to return values as you described, DXL thinks still that it's not a declared problem. i'll try to fix it.

Thanks again Peter,

Kind regards,

Melih

Re: Looping Within Projects
SystemAdmin - Tue Apr 07 07:30:22 EDT 2009

Peter_Albert - Mon Apr 06 10:52:24 EDT 2009

Hmm, I do not fully understand what you are actually doing, but I think you need a bit of clarification w.r.t. the scope of variables, i.e. the level on which variables exist. From the DXL help: "In general, identifiers are in scope following their declaration within the current block, and are available within nested blocks."

Basically, global variables defined at the top of your script, outside of any subroutine, are available everywhere. Local variables, defined within a subroutine, are not available in other subroutines, or at the main level.

So, in order to get information out of a subroutine, the first idea could be to use global variables all over the place. While there are occasions when this is actually the way to go, you should generally try to avoid this and use return variables instead.

The following code snippet might highlight the differences:

string s_global = "I am a global string and live everywhere."
 
string doSomething(string s_input)
{
  string s_local = "I am a local variable and only live inside this subroutine."
  string s_return = "I am the return value."
  print "s_global: " s_global "\n"
  print "s_local: " s_local "\n"
  print "s_input: " s_input "\n"
  s_global = s_global "And now I have been modified."
  return s_return
}
 
string s_result = doSomething("I am the input variable")
print "s_global: " s_global "\n"
print "s_result: " s_result "\n"
// Do not try to
// print "s_local: " s_local "\n"
// as 's_local' does not exist at this level

 


I don't know if this actually answers your question ...
Regards,

Peter

 

Hi again Peter,

Is it normal that i receive all the time expected non-void expression? incorrect arguments for multiList?

Thanks in advance,

Melih
Attachments

attachment_14238273_loop_within_hierarchy_2.dxl

Re: Looping Within Projects
Peter_Albert - Tue Apr 07 07:59:07 EDT 2009

SystemAdmin - Tue Apr 07 07:30:22 EDT 2009
Hi again Peter,

Is it normal that i receive all the time expected non-void expression? incorrect arguments for multiList?

Thanks in advance,

Melih

Well, please don't be offended, but you chose a big project for learning DXL. Something without recursion and without a dialogue box would probably serve the purpose better. O.K., the recursion was part of Louie's and my original answer, but still...

I would really recommend that you give your actual problem a fresh try with the

Item i
for i in current Project do {}

 


approach. Make it as simple as possible to start with. Declare variables up-front. Define useful subroutines. Don't use dialogue boxes.

If you really want to continue your current path, here are a few of the most obvious problems:

In your definition of the multiList, you are using the string variable my_modules, while multiList expects a string array.

Above that line, you assign my_modules the return value of the RecurseFolder routine. However, RecurseFolder is not defined as to return a string array, not even a string variable, as the routine is still a 'void' routine.

However, you planned to return something from RecurseFolder, as you added the line "return my_modules" to the code. Here, my_modules is a Skip list. (Apart from the other problems, let me mention that using the same variable name for two different variables of different type is really a bad idea).

Returning a Skip list from a void return does not work.

When you now try to modify the type of the RecurseFolder routine, you must consider that it is a recursive function, so you must also modify the internal call to the routine, carefully considering what will happen to the return value during the recursion.

That's all for the moment, sorry for being desctructive rather than constructive,

Regards,

Peter

 

Re: Looping Within Projects
SystemAdmin - Tue Apr 07 08:22:33 EDT 2009

Peter_Albert - Tue Apr 07 07:59:07 EDT 2009

Well, please don't be offended, but you chose a big project for learning DXL. Something without recursion and without a dialogue box would probably serve the purpose better. O.K., the recursion was part of Louie's and my original answer, but still...

I would really recommend that you give your actual problem a fresh try with the

Item i
for i in current Project do {}

 


approach. Make it as simple as possible to start with. Declare variables up-front. Define useful subroutines. Don't use dialogue boxes.

If you really want to continue your current path, here are a few of the most obvious problems:

In your definition of the multiList, you are using the string variable my_modules, while multiList expects a string array.

Above that line, you assign my_modules the return value of the RecurseFolder routine. However, RecurseFolder is not defined as to return a string array, not even a string variable, as the routine is still a 'void' routine.

However, you planned to return something from RecurseFolder, as you added the line "return my_modules" to the code. Here, my_modules is a Skip list. (Apart from the other problems, let me mention that using the same variable name for two different variables of different type is really a bad idea).

Returning a Skip list from a void return does not work.

When you now try to modify the type of the RecurseFolder routine, you must consider that it is a recursive function, so you must also modify the internal call to the routine, carefully considering what will happen to the return value during the recursion.

That's all for the moment, sorry for being desctructive rather than constructive,

Regards,

Peter

 

Hi Peter,

No i'm not offended at all, i know that you're not trying to demoralize me but in reverse you're trying to help me, which i think is very kind of you.

I guess I need to settle down a little bit, because actually i have many parts working well, but there is an integration problem. what i think i should think clearly, what i want and how can i achieve this objective.

I do thank you one more time for your precious advices.

Kind regards,

Melih

Re: Looping Within Projects
SystemAdmin - Wed Apr 08 06:07:37 EDT 2009

Peter_Albert - Tue Apr 07 07:59:07 EDT 2009

Well, please don't be offended, but you chose a big project for learning DXL. Something without recursion and without a dialogue box would probably serve the purpose better. O.K., the recursion was part of Louie's and my original answer, but still...

I would really recommend that you give your actual problem a fresh try with the

Item i
for i in current Project do {}

 


approach. Make it as simple as possible to start with. Declare variables up-front. Define useful subroutines. Don't use dialogue boxes.

If you really want to continue your current path, here are a few of the most obvious problems:

In your definition of the multiList, you are using the string variable my_modules, while multiList expects a string array.

Above that line, you assign my_modules the return value of the RecurseFolder routine. However, RecurseFolder is not defined as to return a string array, not even a string variable, as the routine is still a 'void' routine.

However, you planned to return something from RecurseFolder, as you added the line "return my_modules" to the code. Here, my_modules is a Skip list. (Apart from the other problems, let me mention that using the same variable name for two different variables of different type is really a bad idea).

Returning a Skip list from a void return does not work.

When you now try to modify the type of the RecurseFolder routine, you must consider that it is a recursive function, so you must also modify the internal call to the routine, carefully considering what will happen to the return value during the recursion.

That's all for the moment, sorry for being desctructive rather than constructive,

Regards,

Peter

 

Hi Peter again,

it's been a while, so i decided to make remember myself to you, hope you're happy :D. Ok i'll get into the subject. As i was trying to use the module created in Louie's code Module mod = ..., even tough there's no error during the execution i encounter with a problem saying that

-R-E- DXL: <Line:4998> An unexpected error has occurred: doors.exe caused an EXCEPTION_ACCESS_VIOLATION in module doors.exe at 001B:008E4268

and the line responsable for this is

void makeExcelExportUI( Module mod ) {

if ( null excelExportDB ) {

excelExportDB = create( mod, excelTitle, styleFixed | styleCentered ) <--- This is the problematic line

Of course above code continues but the error appears at hte above line. As far as i'm concerned i guess program cannot manage to create an object which poses errors.

Do you have an idea why it could have been occurred? I know it's not easy to make a comment by a simple regard on a little piece of code, but who knows? :s

Thanks in advance, and kind regards,

Melih

Re: Looping Within Projects
SystemAdmin - Wed Apr 08 06:25:05 EDT 2009

SystemAdmin - Wed Apr 08 06:07:37 EDT 2009
Hi Peter again,

it's been a while, so i decided to make remember myself to you, hope you're happy :D. Ok i'll get into the subject. As i was trying to use the module created in Louie's code Module mod = ..., even tough there's no error during the execution i encounter with a problem saying that

-R-E- DXL: <Line:4998> An unexpected error has occurred: doors.exe caused an EXCEPTION_ACCESS_VIOLATION in module doors.exe at 001B:008E4268

and the line responsable for this is

void makeExcelExportUI( Module mod ) {

if ( null excelExportDB ) {

excelExportDB = create( mod, excelTitle, styleFixed | styleCentered ) <--- This is the problematic line

Of course above code continues but the error appears at hte above line. As far as i'm concerned i guess program cannot manage to create an object which poses errors.

Do you have an idea why it could have been occurred? I know it's not easy to make a comment by a simple regard on a little piece of code, but who knows? :s

Thanks in advance, and kind regards,

Melih

To be more precise actually for the time being my code is working perfectly well, when there is a module open however when i try to do the same thing in a loop opening a module then manipulate and close the module that i ve opened so on so forth during its execution it cannot execute, because of this violation error.

Re: Looping Within Projects
SystemAdmin - Wed Apr 08 09:25:27 EDT 2009

SystemAdmin - Wed Apr 08 06:25:05 EDT 2009
To be more precise actually for the time being my code is working perfectly well, when there is a module open however when i try to do the same thing in a loop opening a module then manipulate and close the module that i ve opened so on so forth during its execution it cannot execute, because of this violation error.

Thanks Peter, i figured out where the problem comes from. :D